/**
 * LockboxOptions
 * Options class
 *
 * Created by Nathan Black
 */

#import "LockboxOptions.h"
#import "LockboxStorage.h"

static LockboxOptions *s_lbOptionsInstance;

@interface LockboxOptions (Private)

@end

@implementation LockboxOptions

+ (LockboxOptions *)globalInstance
{
    if (s_lbOptionsInstance == NULL) {
        s_lbOptionsInstance = [[LockboxOptions alloc] init];
    }
    return s_lbOptionsInstance;
}

+ (NSString*)homedir
{
    return [@"~/Library/Lockbox" stringByExpandingTildeInPath];
}

- (void)dealloc
{
    [_tagFilters release];
    _tagFilters = NULL;
    [_optionsPath release];
    _optionsPath = NULL;
    
    [super dealloc];
}

- (id)initWithCoder:(NSCoder *)coder 
{ 
  self = [super init]; 
  _tagFilters = [[coder decodeObjectForKey:@"TagFilters"] retain]; 
  _tagFilterOn = [coder decodeBoolForKey:@"TagFilterOn"]; 
  _showSecretInList = [coder decodeBoolForKey:@"ShowSecretInList"]; 
  _selectToEdit = [coder decodeBoolForKey:@"SelectToEdit"]; 

  return self; 
}

- (void)encodeWithCoder:(NSCoder *)coder 
{ 
  [coder encodeObject:_tagFilters forKey:@"TagFilters"]; 
  [coder encodeBool:_tagFilterOn forKey:@"TagFilterOn"]; 
  [coder encodeBool:_showSecretInList forKey:@"ShowSecretInList"]; 
  [coder encodeBool:_selectToEdit forKey:@"SelectToEdit"]; 
}

-init 
{
    NSString* optionsPath = [[LockboxOptions homedir] stringByAppendingString:@"/Options_v1.dat"];
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:optionsPath]) {
        NSLog(@"options file does exist: %@", _optionsPath);
        @try {
            LockboxOptions *opts = [NSKeyedUnarchiver unarchiveObjectWithFile:optionsPath];
            if (opts == NULL) [NSException raise:NSFileIOException format:@"unarchived object was null"];

            NSLog(@"Data read successfully: filter tag count: %d", [opts->_tagFilters count]);
            [opts validateData];
            self = [opts retain];
        }
        @catch (NSException* ex) {
            @throw;
        }
    }
    else {
        if ((self = [super init])) {
            NSLog(@"Options file not found - loading defaults");
            _tagFilters = [[[NSMutableArray alloc] init] retain];
            _showSecretInList = TRUE;
        }
    }
    
    _optionsPath = [optionsPath retain];
    return self;
}

- (BOOL)save
{
    if (_dirty) {
        if ([NSKeyedArchiver archiveRootObject:self toFile:_optionsPath]) {
            NSLog(@"options saved successfully");
            _dirty = false;
            return true;
        }
        else {
            NSLog(@"--== Options failed to save! ===--");
            return false;
        }
    }
    else {
        NSLog(@"skiping options save as options aren't dirty");
        return TRUE;
    }
}

- (void)validateData
{
    NSAssert(_tagFilters != NULL, @"tagFilter container must never be null");
    /*int i;
    for (i = 0; i < [_tagFilters count]; i++) {
        NSString* tag = [_tagFilters objectAtIndex:i];
        // TODO: why is length correct in the NSLog statement but is evaluated to 0 in the next?        
        NSLog(@"validating tag: %@, len %d", tag, [tag length]);
        NSAssert([tag length] == 0, @"tag is length 0");
    }*/
}

////////////// Accessors ///////////////
- (BOOL)tagFilterOn { return _tagFilterOn; }
- (BOOL)showSecretInList { return _showSecretInList; }
- (BOOL)selectToEdit { return _selectToEdit; }
- (NSMutableArray*)tagFilters { return _tagFilters; }

- (void)setTagFilters:(NSMutableArray*)newFilters
{
    if (newFilters != NULL) {
        [_tagFilters release];
        _tagFilters = [newFilters retain];
        _dirty = true;
    }
}

- (void)setTagFilterOn:(BOOL)filterOn
{
    _tagFilterOn = filterOn;
    _dirty = true;
}

- (void)setShowSecretInList:(BOOL)showSecret
{
    _showSecretInList = showSecret;
    _dirty = true;
}

- (void)setSelectToEdit:(BOOL)selToEdit
{
    _selectToEdit = selToEdit;
    _dirty = true;
}

@end